-- coroutine_test.lua 文件

function test1()
    -- 执行函数
    local function say(sth)
        print(sth)
    end


    print("--1--")
    -- coroutine.create 创建后得到的是一个thread对象，是 suspended 状态，需要 resume 一下。
    local thread1 = coroutine.create(say)
    print(coroutine.status(thread1))  -- suspended
    coroutine.resume(thread1, 123)  -- 传入参数，并唤醒执行
    print(coroutine.status(thread1))  -- dead
    print()
     

    print("--2--")
    -- coroutine.wrap 创建后得到的是一个函数，调用这个函数后，开始运行。
    local thread2 = coroutine.wrap(say)
    thread2('Im 2..')
    print()


    print("--3--")
    local thread3 = coroutine.create(
        function()
            for i = 1,10 do
                print("circle:"..i)
                coroutine.yield(i*10)
            end
        end
    )
    print("beigin.")
    local res, value = coroutine.resume(thread3) -- value 返回 10，证明在执行resume中，已经可以执行到yield(10)
                                                -- 说明resume是阻塞式的。
    print(res, value )
    local res, value = coroutine.resume(thread3) --2
    print(res, value )
    print("end.")
     

print("--4--")
local thread4 = coroutine.create(function(name)
    print(name .. 'begin')
    coroutine.yield();
    print(name .. 'end')
end)
coroutine.resume(thread4,'xiao') -- 传入参数唤醒
coroutine.resume(thread4,'wang') -- 传入参数，但是并没有用，因为是从函数内部重新唤醒，实际上并不拷贝参数。

end

-- 执行任务中间 插入另一个任务。
function test2(  )
    local function always_say()
        local i = 0
        while i<6 do
            i = i + 1
            print("I'm saying",i)
            if i == 3 then
                print("ready to yield")
                coroutine.yield()
            end
        end
    end
    local function always_run()
        local i = 0
        while i<6 do
            i = i + 1
            print("Hi,I'm running",i)
            if i == 3 then
                print("ready to yield")
                coroutine.yield()
            end
        end
    end

    local thread1 = coroutine.create(always_say)
    local thread2 = coroutine.create(always_run)
    coroutine.resume(thread1)  
    -- 到5的时候停止了,跑到另一条线程里面做些事情。
    print("after resume") 
    coroutine.resume(thread2)
    coroutine.resume(thread1) -- 再把他唤醒
    coroutine.resume(thread2) -- 再把他唤醒

end

function test3()
    --生产者-消费者问题
    --现在我就使用Lua的协同程序来完成生产者-消费者这一经典问题。
    local newProductor

    function productor()
        local i = 0
        while i<10 do
            i = i + 1
            send(i)    -- 将生产的物品发送给消费者
        end
    end

    function consumer()
         local i = 0
         while i<10 do
              i = receive()     -- 从生产者那里得到物品
              print("consum:",i)
         end
    end

    function receive()
         local status, value = coroutine.resume(newProductor)
         print(status, value)
         return value
    end

    function send(x)
         coroutine.yield(x)     -- x表示需要发送的值，值返回以后，就挂起该协同程序
    end

    -- 启动程序
    newProductor = coroutine.create(productor)
    consumer()
end

function test4()
      -- 执行函数
    local function say()
        for i=1,10 do
            print("sth")
            os.execute("sleep " .. 1)
        end
    end

    local thread1 = coroutine.create(say)
    print(coroutine.status(thread1))  -- suspended
    coroutine.resume(thread1)           -- 唤醒执行
    print(coroutine.status(thread1))  -- dead


end


local socket = require("socket")
print(socket._VERSION)

function test5()
    local sock = socket.connect("localhost",2000)
    -- 执行函数
    local function receive()
        for i=1,10 do
            local chunk,status = sock:receive(1024)
            print("receive:" .. i)
            print(chunk,status)   
    --        os.execute("sleep " .. 1)
        end
    end

    local thread1 = coroutine.create(receive)
    print(coroutine.status(thread1))  -- suspended
    coroutine.resume(thread1)         -- 唤醒执行
    print(coroutine.status(thread1))  -- dead
end

-- test1()
-- test2()
-- test3()
test4()
print("end")




